# -*- coding: utf-8 -*-
# 姓名:谚语
# 开发时间:2022/6/7 17:56
# 用于测试
from flask_restful import Resource
from comment.models.user import User
from flask import current_app, request, g
from comment.utils.python_sms_sdk_master.example.SendMessage import send_message
import random
import json
from comment.utils.limiter import limiter as lmt
from Shopping.resources.user import constants
from flask_limiter.util import get_remote_address
from comment.utils.shopping_redis import redis_client
from flask_restful.reqparse import RequestParser
from comment.utils import parser
from comment.models import db
from comment.utils.tokens_pyjwt import generate_tokens, verify_tokens
from comment.utils.decorators import login_required


# 我们定义测试的资源类
class Shopping_User(Resource):
    """
            在get函数上加上登录的拦截
    """
    method_decorators = {
        'get': [login_required],
        'post': [login_required]
    }

    def get(self):  # 测试当前get函数必须让用户登录之后才能访问
        current_app.logger.info('我的测试日志')  # 如果Info模式没有报错，可以用debug模式查找错误
        # 这里的代码可能会用到User模型类
        return {'hello': 'get 测试'}

    # 退出登录
    def post(self):
        if g.user_id:
            g.user_id = None
        return {'msg': 'logout Done'}

    def put(self):
        return {'hello': 'put 测试'}


class User_SMS(Resource):
    """
    发送短信
    """

    error_message = 'Tom many requests.'
    # decorators = [
    #     # 三个参数：参数1：限流的速率,参数2：key_func,参数3：如果超出限制之后的提示信息
    #     lmt.limit(constants.LIMIT_SMS_CODE_BY_MOBILE,
    #               key_func=lambda: request.args['phone'],
    #               error_message=error_message),
    #     lmt.limit(constants.LIMIT_SMS_CODE_BY_IP,
    #               key_func=get_remote_address,
    #               error_message=error_message)
    # ]

    def get(self):
        phone = request.args.get('phone'.strip())
        code = random.randint(100000, 999999)
        # result = send_message(phone, (str(code), '5'))  # 返回的是json的字符串
        # result = json.loads(result)  # 把json编成字典
        # 对result的对象添加手机号
        # result ={}
        # result['phone'] = phone
        # print(code)

        # 短信验证码发送成功之后，还需要将短信验证码存放在redis数据库中，以便下次验证，设置验证码是时效为五分钟
        redis_client.setex('shopping:code:{}'.format(phone), constants.SMS_CODE_EXPIRES,
                           code)  # 参数1: key, 参数2: 时效, 参数3: 验证码

        # return result
        return {'smsCode': code}


class AuthorizationCodeResource(Resource):
    """
    提交手机号验证码，开始验证
    """

    def post(self):
        rp = RequestParser()
        rp.add_argument('phone', type=parser.mobile, required=True, location='args')
        rp.add_argument('code', type=parser.regex(r'^\d{6}$'), required=True, location='args')
        args = rp.parse_args()
        phone = args.phone
        code = args.code

        # 从redis数据库中得到之前保存到验证码
        key = 'shopping:code:{}'.format(phone)
        try:
            real_code = redis_client.get(key)  # 从redis中返回的是字节数据
        except ConnectionError as e:
            current_app.logger.error(e)
            return {'message': 'redis db connect error.'}, 400
        # 开始校验
        if not real_code or real_code.decode() != code:
            return {'message': 'Invalid code'}, 400

        return {'phone': phone, 'msg': 'code success.'}


class RegisterUserResource(Resource):

    """
    提交注册用户信息
    填写账号信息，完成用户的注册
    """
    def post(self):
        rp = RequestParser()
        rp.add_argument('phone', type=parser.mobile, required=True, location='form')
        rp.add_argument('username', required=True, location='form')
        rp.add_argument('password', required=True, location='form')
        rp.add_argument('email', type=parser.email, required=True, location='form')
        args = rp.parse_args()
        username = args.username
        password = args.password
        phone = args.phone
        email = args.email

        # 验证用户名是否唯一: 先从mysql数据库中根据当前用户名查询
        u = User.query.filter(User.username == username).first()
        if u:  # 当前用户名已经存在
            current_app.logger.info('{}:用户名已存在，请换一个'.format(username))
            return {'massage': '用户名已存在'}, 400

        # 验证邮箱是否唯一: 先从mysql数据库中根据当前邮箱查询
        u = User.query.filter(User.email == email).first()
        if u:  # 用户名已存在
            current_app.logger.info('{}:邮箱地址已存在，请换一个'.format(username))
            return {'message': '邮箱地址已存在'}, 400

        # 把用户信息保存到数据库中
        u = User(username=username, pwd=password, email=email, status=0, phone=phone)
        db.session.add(u)
        db.session.commit()
        return {'msg': 'ok'}


class UserLoginResource(Resource):
    """
    登录
    """

    def post(self):
        username = request.form.get('username')
        password = request.form.get('password')

        if not all([username, password]):
            return {'message': '数据不完整'}, 402
        user = User.query.filter(User.username == username).first()
        if user:
            if user.check_password(password):
                # 必须把登录成功之后的用户 ID得到token，token返回给前端
                # 创建token
                token = generate_tokens(user.id)
                # verify_tokens(token)
                current_app.logger.info(verify_tokens(token))
                return {'msg': 'Login Success', 'token': token, 'username': username}, 200
        return {'massage': '用户名或者密码错误'}, 400


class UserLoginOutResource(Resource):
    """
    退出登录getOneGoods
    """
    def post(self):
        if g.user_id:
            g.user_id = None
        return {'msg': '退出登录'}


class IsExistPhoneResource(Resource):
    """
    判断手机号是否存在
    """
    def post(self):
        phone = request.form.get('phone')
        user = User.query.filter(User.phone == phone).first()
        if user:  # 如果用户有，则表示手机号存在
            return {'isExist': True, 'message': '此手机号码已注册', 'code': 201}
        return {'msg': '此手机可以注册'}
